﻿function MultiSelectHelper() {
    
    /* Public */

    return {
        /* Set settings for Multiselect */
        configure: function(selector, multiple, allowRemoveSelection, styles)
        {
            var _multiple = multiple != null ? multiple : false;

            var _allowRemoveSelection = allowRemoveSelection != null ? allowRemoveSelection : false;

            $(selector).multiselect
                ({
                    checkAllText: "Marcar todos",
                    uncheckAllText: "Desmarcar todos",
		            selectedText: "# seleccionados",
                    noneSelectedText: "Seleccione..",
                    /*
                        <noneSelectedText>: The default text the select box when no options have been selected
                    */
                            //selectedText: "",
                    /*
                        <selectedText>:
                        The text to display in the select box when options are selected (if selectedList is false).
                        A pound sign (#) will automatically replaced by the number of checkboxes selected.
                        If two pound signs are present in this parameter, the second will be replaced by the total number of checkboxes available. Example: "# of # checked".
                        This parameter also accepts an anonymous function with three arguments: the number of checkboxes checked, the total number of checkboxes, and an array of the checked checkbox DOM elements.
                    */
                    header: true,
                    /*
                        <header>:
                        Either a boolean value denoting whether or not to display the header, or a string value.
                        If you pass a string, the default "check all", "uncheck all", and "close" links will be replaced with the specified text.
                    */
                    multiple: _multiple,
                    selectedList: 1,
                    beforeopen: function(event) {
                    /*
                        Fires right before the menu opens. Prevent the menu from opening by returning false in the handler
                    */
                        if (_multiple) {
                            $(".ui-multiselect-all").show();
                            $(".ui-multiselect-none").show();
                        } else {
                            $(".ui-multiselect-all").hide();
                            $(".ui-multiselect-none").hide();
                        }
                    },
                    open: function(event, ui) {
                    /*
                        Fires after the widget opens
                    */
                        var multiselectFilter = $(this).multiselectfilter("widget");
                        if (multiselectFilter.length == 0)
                            return;

                        //give filter input focus..
                        var multiselect = $(this).multiselect("widget");
                        var header = multiselect.children()[0];
                        var checkboxes = multiselect.children()[1];

                        var filter = $(header).children()[0];
                        var helperReset = $(header).children()[1];

                        var inputFilter = $(filter).children()[0];
                            inputFilter.focus();

                        //var ctrl = multiselect.find(".ui-multiselect-checkboxes");
                        //var selectedOption = $(ctrl.find("label.ui-state-active")[0]);
                        //    ctrl.animate( { scrollTop: selectedOption.offset().top }, 500);
                    },
                    beforeclose: function(event) {
                    /*
                        Fires right before the menu closes. Prevent the menu from closing by returning false in the handler
                    */
                    },
                    close: function(event) {
                    /*
                        Fires after the widget close
                    */
                    },
                    click: function(event, ui)
                    {
                    /*  Fires when a checkbox is checked or unchecked
                        + event: the original event object
                        + ui.value: value of the checkbox
                        + ui.text: text of the checkbox
                        + ui.checked: whether or not the input was checked or unchecked (boolean)
                    */
                    },
                    checkall: function(event, ui) {
                    /*
                        Fires when all the options are checked by either clicking the "check all" link in the header, or when the "checkall" method is programatically called
                    */
                    },
                    uncheckall: function(event, ui) {
                    /*
                        Fires when all the options are all unchecked by either clicking the "uncheck all" link in the header, or when the "uncheckall" method is programatically called
                    */
                    }
                })
                .multiselectfilter
                ({
                    /*
                        <label>:
                        The text to appear left of the input. Defaults to "Filter:"
                    */
                    label: "Filtrar por:",
                    /*
                        <width>:
                        The width of the input in pixels. Defaults to 100px in the style sheet, but you can override this for each instance.
                    */
                    width: 120,
                    /*
                        <placeholder>:
                        The HTML5 placeholder attribute value of the input. Only supported in webkit as of this writing. Defaults to "Enter keywords"
                    */
                    placeholder: "Escribir..",
                    /*
                        <autoReset>:
                        A boolean value denoting whether or not to reset the search box & any filtered options when the widget closes. Defaults to false.
                    */
                    autoReset: false
                });

                //MultiSelect automatically removes multiple="multiple" atribute from <select> if multiple param is set to false.
                //This behavior makes the select to mark the first option as selected if it's the only option available..
                //So I explicitly re-add the multiple="multiple" attribute..
                $(selector).attr("multiple", "multiple");

                //Set control's width to 100%
                this.setWidth(selector, 100, true);

                if ( styles != null )
                {
                    var multiselect = $(selector).next();
                    var keys = Object.keys(styles);
                    for (var i = 0; i < keys.length; i++)
                    {
                        multiselect.css( keys[i], styles[keys[i]] );
                    }
                }

                if (_allowRemoveSelection)
                {
                    var button = $(selector).next();
                    var clsActive = "ui-state-active";
                    var clsHover = "ui-state-hover";
                    var unselectBtn = $(document.createElement("span"));
                    unselectBtn.addClass("ui-icon ui-icon-trash");
                    unselectBtn.attr("style", "float:left;height:16px;width:16px;");
                    unselectBtn.hover(function()
                    {
                        //$(this).parent().addClass(clsActive);
                        $(this).addClass(clsHover);
                    },
                    function()
                    {
                        //$(this).parent().removeClass(clsActive);
                        $(this).removeClass(clsHover);
                    });
                    unselectBtn.click(function(e)
                    {
                        //this.clearSelection(id);
                        var multiselectBtn = $(this).parent();
                        var select = multiselectBtn.prev();

                        clearCurrentSelection(select);

                        e.preventDefault();
                        return false;
                    });
                    button.prepend(unselectBtn);
                }
        },
        /* Returns an array of all selected items */
        getSelected: function(id) {
            //var arrChecked = $("#" + id).val();
            return $("#" + id).multiselect("getChecked").map( function() { return this.value; } ).get();
        },
        /* Returns first selected item's Value */
        getFirstSelectedValue: function(id, defaultValue) {
            var _defaultValue = -1;
            if (defaultValue != null)
                _defaultValue = defaultValue;

            var arrChecked = this.getSelected(id);
            if (arrChecked != null && arrChecked.length > 0)
                return arrChecked[0];
            else
                return _defaultValue;
        },
        /* Returns first selected item's Text */
        getFirstSelectedText: function(id, defaultText) {
            var _defaultText = -1;
            if (defaultText != null)
                _defaultText = defaultText;

            var arrChecked = this.getSelected(id);
            if (arrChecked != null && arrChecked.length > 0)
                return $("#" + id + " option[value='" + arrChecked[0] + "']").text();
            else
                return _defaultText;
        },
        /* Clear all previous selections */
        clearSelection: function(id)
        {
            this.setAll(id, false);
        },
        /* Check/Uncheck option that corresponds to given value */
        setSelected: function(id, values, selected, clearSelection)
        {
            var isMultiple = $("#" + id).multiselect("option", "multiple");
            if ( (isMultiple) && (clearSelection == true) )
            {
                this.clearSelection(id);
            }

            for (var i = 0; i < values.length; i++)
            {
                $("#" + id).multiselect("widget").find('input[value=' +  values[i] + ']').each(
                    function() 
                    {
                        $(this).click();

                        // hack to manually set the "active" visual state on the selected option
                        var clsActive = "ui-state-active";
                        var container = $(this).parent();
                        if (!container.hasClass(clsActive))
                            container.addClass(clsActive);
                    });
            }
        },
        /* Set all items checked/unchecked */
        setAll: function(id, selected) {
            //$("#" + id).multiselect("widget").find(":checkbox").each( function() { this.click(); });
            var select = $("#" + id);
            if (selected)
                select.multiselect("checkAll"); /* methods: "checkAll" / "uncheckAll" */
            else
                clearCurrentSelection(select);
        },
        /* Bind "click" event */
        bindOnChange: function(selector, onChangeFn)
        {
            $(selector).multiselect
            ({
                click: function(event, ui)
                {
                    if ( !isEmpty(onChangeFn) )
                        onChangeFn.call(this, ui.checked, ui.value, ui.text);
                    return true;
                }
            });
        },
        /* Open Multiselect UI */
        open: function(id) {
            $("#" + id).multiselect("open");
        },
        /* Close Multiselect UI */
        close: function(id) {
            $("#" + id).multiselect("close");
        },
        /* Set fixed width to Multiselect control */
        setWidth: function(selector, width, percentage) {
            var _width = percentage != null ? width + "%" : width + "px";
            $(selector).next().css("width", _width);
        },
        /*
            Set css styles to MultiSelect control
            http://api.jquery.com/css/
            Example: $("p").css({"background-color": "yellow", "font-size": "200%"});
        */
        setStyles: function(selector, styles) {
            $(selector).next().css(styles);
        }
    }

    /* Private */
    function clearCurrentSelection(select) {
        select.multiselect("uncheckAll");
        var widget = select.multiselect("widget");
        var list = widget.find("ul.ui-multiselect-checkboxes");
        var clsActive = "ui-state-active";
        var activeSelections = list.find("li label.ui-state-active");
            activeSelections.removeClass(clsActive);             
    }
}
